package com.xjx.programmer.controller;

import com.xjx.programmer.model.DatabaseConnection;
import com.xjx.programmer.model.ExecuteResult;
import com.xjx.programmer.model.ToolSqlConnection;
import com.xjx.programmer.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.sql.DataSource;
import java.util.Map;

/**
 * 数据库操作控制器
 * 提供各种数据库的连接和操作接口
 */
@Slf4j
@RestController
@RequestMapping("/api/database")
public class DatabaseController {

    @Autowired
    private MySqlService mySqlService;

    @Autowired
    private PostgreSqlService postgreSqlService;

    @Autowired
    private MongoDbService mongoDbService;

    @Autowired
    private ElasticsearchService elasticsearchService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private Map<String, DataSource> dataSourceMap;

    @Autowired
    private ToolSqlConnectionService toolSqlConnectionService;

    /**
     * 测试数据库连接
     */
    @PostMapping("/test-connection")
    public ExecuteResult testConnection(@RequestBody DatabaseConnection connection) {
        try {
            boolean isConnected = false;
            String databaseType = connection.getConnectDbType().toLowerCase();
            
            switch (databaseType) {
                case "mysql":
                    isConnected = mySqlService.testConnection(connection);
                    break;
                case "postgresql":
                    isConnected = postgreSqlService.testConnection(connection);
                    break;
                case "mongodb":
                    isConnected = mongoDbService.testConnection(connection);
                    break;
                case "elasticsearch":
                    isConnected = elasticsearchService.testConnection(connection);
                    break;
                case "redis":
                    isConnected = redisService.testConnection(connection);
                    break;
                default:
                    return ExecuteResult.builder()
                            .success(false)
                            .message("不支持的数据库类型: " + databaseType)
                            .errorMessage("支持的数据库类型: mysql, postgresql, mongodb, elasticsearch, redis")
                            .build();
            }
            
            return ExecuteResult.builder()
                    .success(isConnected)
                    .message(isConnected ? "连接成功" : "连接失败")
                    .build();
                    
        } catch (Exception e) {
            log.error("测试数据库连接失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("连接测试异常")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 执行 MySQL SQL 语句
     */
    @PostMapping("/mysql/execute")
    public ExecuteResult executeMySql(@RequestBody Map<String, String> request) {
        try {
            String sql = request.get("sql");
            if (sql == null || sql.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("SQL 语句不能为空")
                        .errorMessage("请提供有效的 SQL 语句")
                        .build();
            }
            
            DataSource dataSource = dataSourceMap.get("mysql");
            if (dataSource == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("MySQL 数据源未配置")
                        .errorMessage("请先配置 MySQL 连接信息")
                        .build();
            }
            
            return mySqlService.executeSql(dataSource, sql);
            
        } catch (Exception e) {
            log.error("执行 MySQL SQL 失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("执行失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 执行 PostgreSQL SQL 语句
     */
    @PostMapping("/postgresql/execute")
    public ExecuteResult executePostgreSql(@RequestBody Map<String, String> request) {
        try {
            String sql = request.get("sql");
            if (sql == null || sql.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("SQL 语句不能为空")
                        .errorMessage("请提供有效的 SQL 语句")
                        .build();
            }
            
            DataSource dataSource = dataSourceMap.get("postgresql");
            if (dataSource == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("PostgreSQL 数据源未配置")
                        .errorMessage("请先配置 PostgreSQL 连接信息")
                        .build();
            }
            
            return postgreSqlService.executeSql(dataSource, sql);
            
        } catch (Exception e) {
            log.error("执行 PostgreSQL SQL 失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("执行失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 执行 MongoDB 命令
     */
    @PostMapping("/mongodb/command")
    public ExecuteResult executeMongoCommand(@RequestBody Map<String, Object> request) {
        try {
            String command = (String) request.get("command");
            if (command == null || command.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("命令不能为空")
                        .errorMessage("请提供有效的 MongoDB 命令")
                        .build();
            }
            
            DatabaseConnection connection = parseConnectionFromRequest(request);
            return mongoDbService.executeCommand(connection, command);
            
        } catch (Exception e) {
            log.error("执行 MongoDB 命令失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("执行失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 查询 MongoDB 文档
     */
    @PostMapping("/mongodb/find")
    public ExecuteResult findMongoDocuments(@RequestBody Map<String, Object> request) {
        try {
            String collectionName = (String) request.get("collection");
            String filter = (String) request.get("filter");
            
            if (collectionName == null || collectionName.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("集合名称不能为空")
                        .errorMessage("请提供有效的集合名称")
                        .build();
            }
            
            DatabaseConnection connection = parseConnectionFromRequest(request);
            return mongoDbService.findDocuments(connection, collectionName, filter);
            
        } catch (Exception e) {
            log.error("查询 MongoDB 文档失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("查询失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 插入 MongoDB 文档
     */
    @PostMapping("/mongodb/insert")
    public ExecuteResult insertMongoDocument(@RequestBody Map<String, Object> request) {
        try {
            String collectionName = (String) request.get("collection");
            String document = (String) request.get("document");
            
            if (collectionName == null || collectionName.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("集合名称不能为空")
                        .errorMessage("请提供有效的集合名称")
                        .build();
            }
            
            if (document == null || document.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("文档内容不能为空")
                        .errorMessage("请提供有效的文档内容")
                        .build();
            }
            
            DatabaseConnection connection = parseConnectionFromRequest(request);
            return mongoDbService.insertDocument(connection, collectionName, document);
            
        } catch (Exception e) {
            log.error("插入 MongoDB 文档失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("插入失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 执行 Elasticsearch 查询
     */
    @PostMapping("/elasticsearch/search")
    public ExecuteResult searchElasticsearch(@RequestBody Map<String, Object> request) {
        try {
            String index = (String) request.get("index");
            String query = (String) request.get("query");
            
            if (index == null || index.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("索引名称不能为空")
                        .errorMessage("请提供有效的索引名称")
                        .build();
            }
            
            DatabaseConnection connection = parseConnectionFromRequest(request);
            return elasticsearchService.executeQuery(connection, index, query);
            
        } catch (Exception e) {
            log.error("执行 Elasticsearch 查询失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("查询失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 创建 Elasticsearch 索引
     */
    @PostMapping("/elasticsearch/create-index")
    public ExecuteResult createElasticsearchIndex(@RequestBody Map<String, Object> request) {
        try {
            String indexName = (String) request.get("indexName");
            String mapping = (String) request.get("mapping");
            
            if (indexName == null || indexName.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("索引名称不能为空")
                        .errorMessage("请提供有效的索引名称")
                        .build();
            }
            
            DatabaseConnection connection = parseConnectionFromRequest(request);
            return elasticsearchService.createIndex(connection, indexName, mapping);
            
        } catch (Exception e) {
            log.error("创建 Elasticsearch 索引失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("创建索引失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 执行 Redis 命令
     */
    @PostMapping("/redis/execute")
    public ExecuteResult executeRedisCommand(@RequestBody Map<String, Object> request) {
        try {
            String command = (String) request.get("command");
            if (command == null || command.trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("命令不能为空")
                        .errorMessage("请提供有效的 Redis 命令")
                        .build();
            }
            
            // 从请求中解析连接信息
            DatabaseConnection connection = parseConnectionFromRequest(request);
            if (connection == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("连接信息不完整")
                        .errorMessage("请提供 host, port 等连接信息")
                        .build();
            }

            return redisService.executeCommand(connection, command);

        } catch (Exception e) {
            log.error("执行 Redis 命令失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("执行失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 保存数据库连接
     */
    @PostMapping("/connection/save")
    public ExecuteResult saveConnection(@RequestBody ToolSqlConnection connection) {
        try {
            if (connection.getAccountNo() == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("账户编号不能为空")
                        .errorMessage("请提供有效的账户编号")
                        .build();
            }
            
            if (connection.getConnectName() == null || connection.getConnectName().trim().isEmpty()) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("连接名称不能为空")
                        .errorMessage("请提供有效的连接名称")
                        .build();
            }
            
            return toolSqlConnectionService.saveConnection(connection);
            
        } catch (Exception e) {
            log.error("保存数据库连接失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("保存连接失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 查询用户的数据库连接列表
     */
    @GetMapping("/connection/list")
    public ExecuteResult getConnectionsByAccount(@RequestParam Long accountNo) {
        try {
            if (accountNo == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("账户编号不能为空")
                        .errorMessage("请提供有效的账户编号")
                        .build();
            }
            
            return toolSqlConnectionService.getConnectionsByAccount(accountNo);
            
        } catch (Exception e) {
            log.error("查询数据库连接列表失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("查询失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 根据ID查询连接详情
     */
    @GetMapping("/connection/{id}")
    public ExecuteResult getConnectionById(@PathVariable Long id) {
        try {
            if (id == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("连接ID不能为空")
                        .errorMessage("请提供有效的连接ID")
                        .build();
            }
            
            return toolSqlConnectionService.getConnectionById(id);
            
        } catch (Exception e) {
            log.error("查询数据库连接详情失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("查询失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 删除数据库连接
     */
    @DeleteMapping("/connection/{id}")
    public ExecuteResult deleteConnection(@PathVariable Long id, @RequestParam Long accountNo) {
        try {
            if (id == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("连接ID不能为空")
                        .errorMessage("请提供有效的连接ID")
                        .build();
            }
            
            if (accountNo == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("账户编号不能为空")
                        .errorMessage("请提供有效的账户编号")
                        .build();
            }
            
            return toolSqlConnectionService.deleteConnection(id, accountNo);
            
        } catch (Exception e) {
            log.error("删除数据库连接失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("删除连接失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 更新数据库连接
     */
    @PutMapping("/connection/update")
    public ExecuteResult updateConnection(@RequestBody ToolSqlConnection connection) {
        try {
            if (connection.getId() == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("连接ID不能为空")
                        .errorMessage("请提供有效的连接ID")
                        .build();
            }
            
            if (connection.getAccountNo() == null) {
                return ExecuteResult.builder()
                        .success(false)
                        .message("账户编号不能为空")
                        .errorMessage("请提供有效的账户编号")
                        .build();
            }
            
            return toolSqlConnectionService.updateConnection(connection);
            
        } catch (Exception e) {
            log.error("更新数据库连接失败", e);
            return ExecuteResult.builder()
                    .success(false)
                    .message("更新连接失败")
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    /**
     * 从请求中解析数据库连接信息
     */
    private DatabaseConnection parseConnectionFromRequest(Map<String, Object> request) {
        return DatabaseConnection.builder()
                .databaseType((String) request.get("databaseType"))
                .url((String) request.get("url"))
                .username((String) request.get("username"))
                .password((String) request.get("password"))
                .databaseName((String) request.get("databaseName"))
                .host((String) request.get("host"))
                .port(request.get("port") != null ? Integer.parseInt(request.get("port").toString()) : null)
                .build();
    }




}
